﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Sayeet
{
    public delegate void ProcessMessageDelegate(XMPPMessage message, XMPPConnection connection);

    public partial class RosterWindow : Form
    {
        public DebugWindow debug;
        private SettingsWindow settings;
        bool exiting;
        AppData appData;

        public RosterWindow(AppData ad)
        {
            appData = ad;
            InitializeComponent();
            exiting = false;


        }

        private void RosterWindow_Load(object sender, EventArgs e)
        {
            appData.debugWindow = new DebugWindow(appData);
            appData.debugWindow.Show();


            appData.debugWindow.addText("Started.");

            appData.chatWindow = new ChatWindow(appData);

            this.contactList.appData = this.appData;

            // **************** Tests for ContactList *******************
            //RosterItem r1 = new RosterItem("janek@jo", null, RosterItem.enSubscription.both, "Friends", RosterItem.enStatus.online, appData);
            //RosterItem r2 = new RosterItem("janek@jo", "jolo", RosterItem.enSubscription.both, "Friends", RosterItem.enStatus.away, appData);
            //RosterItem r3 = new RosterItem("janesd", null, RosterItem.enSubscription.both, "Work", RosterItem.enStatus.offline, appData);
            //RosterItem r4 = new RosterItem("ala", null, RosterItem.enSubscription.both, "Friends", RosterItem.enStatus.offline, appData);
            //RosterItem r5 = new RosterItem("ala1", null, RosterItem.enSubscription.both, "Classmate", RosterItem.enStatus.online, appData);
            //RosterItem r6 = new RosterItem("nowy", "Nowiutki", RosterItem.enSubscription.both, "New", RosterItem.enStatus.online, appData);

            //appData.newContact(r2);
            //appData.newContact(r1);
            //appData.newContact(r3);
            //appData.newContact(r4);
            //appData.newContact(r5);
            //appData.newContact(r6);
            //contactList.updateList();
            // **************************************************************

            setStatus("Welcome to Sayeet!");
         //   appData.askSubscription(new JID("jis"));
            //appData.connection.RcvQueueUpdated += new RcvQueueUpdatedEventHandler(connection_RcvQueueUpdated);
        }

        public void AddRcvQueueHandler()
        {
            appData.connection.RcvQueueUpdated += new RcvQueueUpdatedEventHandler(connection_RcvQueueUpdated);
        }

        private void rosterTrayIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (Visible)
                Hide();
            else
                Show();
        }

        private void showRosterWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Show();
        }

        private void hideRosterWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Hide();
        }

        private void quitSayeetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Exit();
        }

        private void RosterWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!exiting)
            {
                e.Cancel = true;
                Hide();
            }
        }

        public void setStatus(string message)
        {
            rosterStatusLabel.Text = message;
        }

        private void quitButton_Click(object sender, EventArgs e)
        {
            Exit();
        }

        private void settingsButton_Click(object sender, EventArgs e)
        {
            settings = new SettingsWindow();
            settings.Show();
        }

        private void connectButton_Click(object sender, EventArgs e)
        {
            appData.startConnection();
        }

        private void disconnectButton_Click(object sender, EventArgs e)
        {
            appData.stopConnection();
        }

        private void Exit()
        {
            exiting = true;
            appData.stopConnection();
            Application.Exit();
        }

        private void contactList_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Parent == null) //If node is a group node
            {
                if (e.Node.IsExpanded)
                {
                    e.Node.Expand();
                    appData.debugWindow.addText(e.Node.Text + " node expanded");
                }
                else
                {
                    e.Node.Collapse();
                    appData.debugWindow.addText(e.Node.Text + " node collapsed");
                }
            }
            else
            {
                RosterItem selected = (RosterItem)e.Node.Tag;
                selected.startChat();
            }
        }

        private void contactList_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (e.Node.Parent != null)
                {
                    contactList.SelectedNode = e.Node;
                    nodeMenu.Show(contactList, e.Location);
                }

            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode groupNode = contactList.SelectedNode.Parent;
            if (groupNode.Nodes.Count == 1)
            {
                groupNode.Remove();
            }
            else
            {
                RosterItem deleteContact = (RosterItem)contactList.SelectedNode.Tag;
                appData.removeContact(deleteContact);
            }
        }

        private void getInfoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            InfoBox info = new InfoBox();
            RosterItem selectedContact = (RosterItem)contactList.SelectedNode.Tag;
            info.setName(selectedContact.Name);
            info.setJid(selectedContact.Jid.ToString());
            info.setStatus(selectedContact.Status);
            info.setSubscription(selectedContact.Subscription);
            info.Show();
        }

        private void chatToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RosterItem selectedContact = (RosterItem)contactList.SelectedNode.Tag;
            selectedContact.startChat();
        }

        private void addContactButton_Click(object sender, EventArgs e)
        {
            if (appData.Connected)
            {
                AddContactWindow dialog = new AddContactWindow();
                List<string> groups = new List<string>();
                foreach (TreeNode node in contactList.Nodes)
                {
                    groups.Add((string)node.Text);
                }
                dialog.groups = groups;
                dialog.appData = appData;
                dialog.Show();
            }
        }

        public void updateList()
        {
            contactList.updateList();
        }

        private void onlineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            appData.SetPresence(XMPPConnection.Status.online);
        }

        private void awayToolStripMenuItem_Click(object sender, EventArgs e)
        {
            appData.SetPresence(XMPPConnection.Status.away);
        }


        // Invoke the event form ReceiverJob
        private void connection_RcvQueueUpdated(XMPPConnection conn)
        {
            XMPPMessage m = null;
            while ((m = conn.GetMessage()) != null)
            {
                if (InvokeRequired)
                    Invoke(new ProcessMessageDelegate(appData.ProcessMessage), m, conn);
                else
                    appData.ProcessMessage(m, conn);

            }
        }


    }


    public class ContactTree : TreeView
    {
        public AppData appData;
        public TreeNode findGroup(string group)
        {
            foreach (TreeNode node in this.Nodes)
            {
                if (node.Text == group)
                    return node;
            }
            return null;
        }

        public void addContact(RosterItem contact)
        {
            {
                TreeNode groupNode = findGroup(contact.Group);
                TreeNode newContact = new TreeNode();
                newContact.Text = contact.Name;
                newContact.Tag = contact;
                switch (contact.Status)
                {
                    case XMPPConnection.Status.online:
                        newContact.ImageIndex = 0;
                        newContact.SelectedImageIndex = 0;
                        break;
                    case XMPPConnection.Status.away:
                        newContact.ImageIndex = 1;
                        newContact.SelectedImageIndex = 1;
                        break;
                    case XMPPConnection.Status.offline:
                        newContact.ImageIndex = 2;
                        newContact.SelectedImageIndex = 2;
                        break;
                    default:
                        break;
                }



                if (groupNode == null)
                {
                    groupNode = this.Nodes.Add(contact.Group); // Create group node
                    groupNode.SelectedImageIndex = 3;
                    groupNode.ImageIndex = 3;
                }
                groupNode.Nodes.Add(newContact);
            }
        }

        public void updateList()
        {
            BeginUpdate();
            this.Nodes.Clear();

            if (appData.contacts.Count > 0)
            {
                appData.contacts.Sort(delegate(RosterItem r1, RosterItem r2)
                            {
                                if (r1.Group == r2.Group)
                                {
                                    if (r1.Status == r2.Status)
                                        return r1.Name.CompareTo(r2.Name);
                                    else
                                        return r1.Status.CompareTo(r2.Status);
                                }
                                else
                                    return r1.Group.CompareTo(r2.Group);

                            });
            }

            foreach (RosterItem contact in appData.contacts)
            {
                addContact(contact);
            }

           ExpandAll();
           EndUpdate();

        }

        public void removeNode(TreeNode node)
        {
            this.BeginUpdate();
            node.Remove();
            //TODO: XMPP remove
            this.EndUpdate();
        }

    }




}
